package
{
	public class NinjaGame
	{
		public var LoadDemo:Function;
		public var StartRecordingDemo:Function;
		public var StopRecordingDemo:Function;
		public var StartDemoPlayback:Function;
		public var StopDemoPlayback:Function;
		public var DumpDemoData:Function;
		public var RecordFrame:Function;
		public var GetInputState_DemoPlayback:Function;
		public var KEYDEF_L:Number;
		public var KEYDEF_R:Number;
		public var KEYDEF_J:Number;
		public var playerMaxTime:Number;
		public var playerCurTime:Number;
		public var playerStartingTime:Number;
		public var playerBonusTime:Number;
		public var RECORDING_DEMO:Boolean;
		public var mapStr:String;
		public var objStr:String;
		public var tickCounter:Number;
		public var demoTickCount:Number;
		public var GetInputState:Function;

		public function NinjaGame()
		{
			this.LoadDemo = this.LoadDemo_Complex;
			this.StartRecordingDemo = this.StartRecordingDemo_Complex;
			this.StopRecordingDemo = this.StopRecordingDemo_Complex;
			this.StartDemoPlayback = this.StartDemoPlayback_Complex;
			this.StopDemoPlayback = this.StopDemoPlayback_Complex;
			this.DumpDemoData = this.DumpDemoData_Complex;
			this.RecordFrame = this.RecordFrame_Complex;
			this.GetInputState_DemoPlayback = this.GetInputState_DemoPlayback_Complex;
			this.KEYDEF_L = Main.getInstance().userdata.GetLeftKey();
			this.KEYDEF_R = Main.getInstance().userdata.GetRightKey();
			this.KEYDEF_J = Main.getInstance().userdata.GetJumpKey();
			this.playerMaxTime = 3600;
			this.playerCurTime = 3600;
			this.playerStartingTime = 3600;
			this.playerBonusTime = 80;
			this.RECORDING_DEMO = false;
			this.mapStr = "";
			this.objStr = "";
			this.tickCounter = 0;
			this.demoTickCount = 0;
			this.GetInputState = this.GetInputState_Normal;
		}

		public function SetKeyDefs(jdef, ldef, rdef):void
		{
			this.KEYDEF_L = ldef;
			this.KEYDEF_R = rdef;
			this.KEYDEF_J = jdef;
		}

		public function InitNewGame():void
		{
			this.playerCurTime = (this.playerStartingTime = this.playerMaxTime);
			this.tickCounter = 0;
		}

		public function InitNewLevel():void
		{
			this.playerStartingTime = this.playerCurTime;
			this.tickCounter = 0;
		}

		public function InitRetryLevel():void
		{
			this.playerCurTime = this.playerStartingTime;
			this.tickCounter = 0;
		}

		public function Tick():void
		{
			Main.getInstance().debug_rend.Clear();
			Main.getInstance().static_rend.Clear();
			Main.getInstance().objects.Tick();
			PlayerObject.player.Tick();
			this.tickCounter++;
		}

		public function Draw():void
		{
			Main.getInstance().objects.Draw();
		}

		public function DrawPlayerTime():void
		{
			Main.getInstance().gui.DrawPlayerTime(this.playerCurTime, this.playerMaxTime);
		}

		public function FillPlayerTime():void
		{
			Main.getInstance().gui.FillPlayerTime(this.playerCurTime, this.playerMaxTime);
		}

		public function GetPlayerTime():Number
		{
			return(this.playerCurTime);
		}

		public function GetTime():Number
		{
			return(this.tickCounter);
		}

		public function GiveBonusTime():void
		{
			this.playerCurTime = this.playerCurTime + this.playerBonusTime;
		}

		public static const KILLTYPE_ELECTRIC:Number = 0;
		public static const KILLTYPE_EXPLOSIVE:Number = 1;
		public static const KILLTYPE_WEAKBULLET:Number = 2;
		public static const KILLTYPE_HARDBULLET:Number = 3;
		public static const KILLTYPE_FALL:Number = 4;
		public static const KILLTYPE_LASER:Number = 5;
		// 我添加的
		public static const KILLTYPE_SOFTBULLET:Number = 6;

		public function KillPlayer(killtype, fx, fy, px, py, obj):void
		{
			if (!PlayerObject.player.isDead)
			{
				PlayerObject.player.Die(fx, fy, px, py, killtype);
				if (killtype == NinjaGame.KILLTYPE_EXPLOSIVE)
				{
					PlayerObject.player.raggy.Explode();
				}
				Main.getInstance().App_PlayerDeathEvent();
				var _local1 = "You were killed by ";
				var _local2 = Main.getInstance().objects.GetObjType(obj);
				if (_local2 == ObjectManager.OBJTYPE_PLAYER)
				{
					_local1 = _local1 + "yourself!! looooooser!!";
				}
				else
				{
					_local1 = _local1 + ("a " + obj.name);
				}
				Main.getInstance().console.AddLine(_local1);
				return;
			}
		}

		public static const LEVEL_SEPERATION_CHAR:String = "|";
		public static const OBJECT_SEPERATION_CHAR:String = "!";
		public static const OBJTYPE_SEPERATION_CHAR:String = "^";
		public static const OBJPARAM_SEPERATION_CHAR:String = ",";
		public static const DEMOFRAME_SEPERATION_CHAR:String = "|";
		public static const DEMOTICKS_SEPERATION_CHAR:String = ":";

		public function DumpLevelData():String
		{
			var _local1 = this.DumpMapData();
			var _local3 = this.DumpObjData();
			var _local2 = (_local1 + NinjaGame.LEVEL_SEPERATION_CHAR) + _local3;
			return(_local2);
			return(_local3);
		}

		public function DumpMapData()
		{
			var _local1 = Main.getInstance().tiles.GetTileStates();
			return(_local1);
			return(_local1);
		}

		public function DumpObjData()
		{
			var _local1 = Main.getInstance().objects.GetObjectStates();
			return(_local1);
			return(_local1);
		}

		//
		public static const PINPUT_L:int = 0;
		public static const PINPUT_R:int = 1;
		public static const PINPUT_J:int = 2;
		public static const PINPUT_JTRIG:int = 3;
		//
		public static const BITSHIFT_L:int = 0;
		public static const BITSHIFT_R:int = 1;
		public static const BITSHIFT_J:int = 2;
		public static const BITSHIFT_JTRIG:int = 3;
		//
		public static const BITMASK_L:int = 1 << NinjaGame.BITSHIFT_L;
		public static const BITMASK_R:int = 1 << NinjaGame.BITSHIFT_R;
		public static const BITMASK_J:int = 1 << NinjaGame.BITSHIFT_J;
		public static const BITMASK_JTRIG:int = 1 << NinjaGame.BITSHIFT_JTRIG;
		public static const BITMASK_FRAME:int = NinjaGame.BITMASK_L + NinjaGame.BITMASK_R + NinjaGame.BITMASK_J + NinjaGame.BITMASK_JTRIG;
		//
		public static const shiftList:Array = [0, 4, 8, 12, 16, 20, 24];
		public static const NUM_BITPACKS:Number = NinjaGame.shiftList.length;

		public function GetInputState_Normal(inList)
		{
			var _local1 = inList;
			_local1[NinjaGame.PINPUT_L] = KeyManager.isDown(this.KEYDEF_L);
			_local1[NinjaGame.PINPUT_R] = KeyManager.isDown(this.KEYDEF_R);
			var _local3 = _local1[NinjaGame.PINPUT_J];
			_local1[NinjaGame.PINPUT_J] = KeyManager.isDown(this.KEYDEF_J) || (KeyManager.isDown(90));
			_local1[NinjaGame.PINPUT_JTRIG] = _local1[NinjaGame.PINPUT_J] && (!_local3);
			if (this.RECORDING_DEMO)
			{
				this.RecordFrame(_local1);
			}
		}

		public function GetDemoTickCount():Number
		{
			return(this.demoTickCount);
		}

		public var demoList:Array;
		public var demoCurShift:Number;

		public function StartRecordingDemo_Complex():void
		{
			Main.getInstance().console.AddLine("-demo recording started..");
			this.GetInputState = this.GetInputState_Normal;
			this.RECORDING_DEMO = true;
			this.demoTickCount = 0;
			this.demoList = new Array();
			this.demoList.push(0);
			this.demoCurShift = 0;
		}

		public function StopRecordingDemo_Complex():void
		{
			this.RECORDING_DEMO = false;
			this.demoTickCount = this.demoTickCount - 1;
			if (this.demoTickCount < 0)
			{
				this.demoTickCount = 0;
			}
			Main.getInstance().console.AddLine("-demo recording stopped.");
		}

		public function LoadDemo_Complex(demoStr):void
		{
			var temp = demoStr.split(NinjaGame.DEMOTICKS_SEPERATION_CHAR);
			this.demoTickCount = Number(temp[0]);
			var _local2 = temp[1].split(NinjaGame.DEMOFRAME_SEPERATION_CHAR);
			this.demoList = new Array();
			var _local1 = 0;
			while (_local1 < _local2.length)
			{
				this.demoList[_local1] = Number(_local2[_local1]);
				_local1++;
			}
			Main.getInstance().console.AddLine("-demo loaded.");
		}

		public var demoCurPlayEntry:Number;

		public function StartDemoPlayback_Complex():void
		{
			Main.getInstance().console.AddLine("-demo playback started..");
			this.GetInputState = this.GetInputState_DemoPlayback;
			this.demoCurPlayEntry = 0;
			this.demoCurShift = 0;
		}

		public function StopDemoPlayback_Complex():void
		{
			Main.getInstance().console.AddLine("-demo playback stopped.");
			this.GetInputState = this.GetInputState_Normal;
		}

		public function DumpDemoData_Complex():String
		{
			var _local2 = "";
			_local2 = _local2 + (this.demoTickCount + NinjaGame.DEMOTICKS_SEPERATION_CHAR);
			var _local1 = 0;
			while (_local1 < this.demoList.length)
			{
				_local2 = _local2 + this.demoList[_local1];
				_local2 = _local2 + NinjaGame.DEMOFRAME_SEPERATION_CHAR;
				_local1++;
			}
			if (0 < _local2.length)
			{
				var lastD = _local2.lastIndexOf(NinjaGame.DEMOFRAME_SEPERATION_CHAR);
				_local2 = _local2.substring(0, lastD);
			}
			return(_local2);
		}

		public function RecordFrame_Complex(inList):void
		{
			var _local2 = inList;
			if (3600 <= this.demoList.length)
			{
				this.StopRecordingDemo();
			}
			else
			{
				var bit_l = Number(_local2[NinjaGame.PINPUT_L]);
				var _local3 = Number(_local2[NinjaGame.PINPUT_R]);
				var bit_j = Number(_local2[NinjaGame.PINPUT_J]);
				var bit_jtrig = Number(_local2[NinjaGame.PINPUT_JTRIG]);
				var framebits = ((((0 + (bit_l << NinjaGame.BITSHIFT_L)) + (_local3 << NinjaGame.BITSHIFT_R)) + (bit_j << NinjaGame.BITSHIFT_J)) + (bit_jtrig << NinjaGame.BITSHIFT_JTRIG));
				var curShift = NinjaGame.shiftList[this.demoCurShift];
				this.demoList[this.demoList.length - 1] = this.demoList[this.demoList.length - 1] + (framebits << curShift);
				this.demoCurShift++;
				if (NinjaGame.NUM_BITPACKS <= this.demoCurShift)
				{
					this.demoList.push(0);
					this.demoCurShift = 0;
				}
				this.demoTickCount++;
			}
		}

		public function GetInputState_DemoPlayback_Complex(inList):void
		{
			var _local3 = inList;
			if (this.demoTickCount <= Main.getInstance().game.GetTime())
			{
				this.StopDemoPlayback();
			}
			else
			{
				var _local1 = this.demoList[this.demoCurPlayEntry];
				_local1 = _local1 >> NinjaGame.shiftList[this.demoCurShift];
				_local1 = _local1 & NinjaGame.BITMASK_FRAME;
				var bit_l = (_local1 & NinjaGame.BITMASK_L);
				var bit_r = (_local1 & NinjaGame.BITMASK_R);
				var bit_j = (_local1 & NinjaGame.BITMASK_J);
				var bit_jtrig = (_local1 & NinjaGame.BITMASK_JTRIG);
				_local3[NinjaGame.PINPUT_L] = Boolean(bit_l);
				_local3[NinjaGame.PINPUT_R] = Boolean(bit_r);
				_local3[NinjaGame.PINPUT_J] = Boolean(bit_j);
				_local3[NinjaGame.PINPUT_JTRIG] = Boolean(bit_jtrig);
				this.demoCurShift++;
				if (NinjaGame.NUM_BITPACKS <= this.demoCurShift)
				{
					this.demoCurPlayEntry++;
					this.demoCurShift = 0;
				}
			}
		}

		public var levStr:String;

		public function InitLoadLevel(str):void
		{
			this.levStr = str;
			var _local1 = this.levStr.split(NinjaGame.LEVEL_SEPERATION_CHAR);
			this.InitLoadMap(_local1[0]);
			this.InitLoadObjects(_local1[1]);
		}

		public var CUR_CHAR:Number;
		public var NUM_ROWS:Number;
		public var NUM_COLS:Number;
		public var CUR_COL:Number;
		public var CUR_ROW:Number;
		public var MAP_LOADED:Boolean;

		public function InitLoadMap(str):void
		{
			this.mapStr = str;
			this.CUR_CHAR = 0;
			this.NUM_ROWS = Main.getInstance().tiles.cols;
			this.NUM_COLS = Main.getInstance().tiles.rows;
			this.CUR_COL = 0;
			this.CUR_ROW = 0;
			this.MAP_LOADED = false;
		}

		public function LoadingMap():Boolean
		{
			if (this.NUM_ROWS <= this.CUR_ROW)
			{
				this.CUR_COL++;
				this.CUR_ROW = 0;
			}
			if (this.NUM_COLS <= this.CUR_COL)
			{
				return(false);
			}
			Main.getInstance().tiles.SetTileState(this.CUR_COL, this.CUR_ROW, this.mapStr.charCodeAt(this.CUR_CHAR));
			this.CUR_CHAR++;
			this.CUR_ROW++;
			return(true);
		}

		public var oStrArray:Array;
		public var CURRENT_OBJ_LOADING:Number;
		public var objParamList:Array;
		public var objUIDList:Array;

		public function InitLoadObjects(str):void
		{
			Main.getInstance().objects.Clear();
			this.objStr = str;
			if (0 < this.objStr.length)
			{
				this.oStrArray = this.objStr.split(NinjaGame.OBJECT_SEPERATION_CHAR);
				var _local1 = 0;
				while (_local1 < this.oStrArray.length)
				{
					_local1++;
				}
				this.CURRENT_OBJ_LOADING = 0;
				this.objParamList = new Array();
				this.objUIDList = new Array();
			}
			else
			{
				this.CURRENT_OBJ_LOADING = 0;
				this.oStrArray = new Array();
				this.objParamList = new Array();
				this.objUIDList = new Array();
			}
		}

		public function InitReloadObjects():void
		{
			this.InitLoadObjects(this.objStr);
		}

		public function LoadingObjects():Boolean
		{
			if (this.CURRENT_OBJ_LOADING < this.oStrArray.length)
			{
				var temp = this.oStrArray[this.CURRENT_OBJ_LOADING].split(NinjaGame.OBJTYPE_SEPERATION_CHAR);
				var _local1 = temp[1].split(NinjaGame.OBJPARAM_SEPERATION_CHAR);
				for (var _local3 in _local1)
				{
					_local1[_local3] = Number(_local1[_local3]);
				}
				this.objUIDList.push(Main.getInstance().objects.SpawnGameObject(Number(temp[0]), _local1));
				this.objParamList.push(_local1);
				this.CURRENT_OBJ_LOADING++;
				return(true);
			}
			return(false);
		}
	}
}